Project1 Introduction:

The goal of this project1 is going to provide analysis mainly on 3 authors (Keynes, Ricardo, Smith) from capitalism.

Outline of project

  • Packages loading
  • Data edit & clean
  • Exploratory Data Analysis (EDA)
    • Title
    • Author
    • School
    • Original publication date & Corpus edition date
    • Summary tree diagram for school, author & title
  • Analysis of capitalism
    • Why Capitalism ?
    • Word cloud for capitalism
    • Sentence_length variation by author
    • Comparison of top 10 frequent words by author
  • Analysis of sentiment
    • Keynes
    • Ricardo
    • Simith
  • Conclusion

Packages loading

library(dplyr)
library(ggplot2)
library(plotly) # tree diagram 
library(tm)
# word cloud
library(wordcloud)
library(RColorBrewer)
library(SnowballC)
library(gridExtra) # arrange plot for sentence_length comparison
library(syuzhet) # sentiment analysis

Date Edit & Clean

There are 360808 observations with 11 variables (title, author, school, sentence_spacy, sentence_str, original_publication_date, corpus_edition_date, sentence_length, sentence_lowered, tokenized_txt, lemmatized_str) in this dataset. Only 1 numeric variable (sentence_length), 2 time variables (original_publication_date, corpus_edition_date), and the rest are character variables. No missing values / ‘nan’ exists for each variable and no duplicated observations in the dataset.

df = read.csv('/Users/sherry/Documents/Github/fall2022-project1-YudanZhang/data/philosophy_data.csv')
head(df)
sprintf('the number of rows: %d', dim(df)[1])
[1] "the number of rows: 360808"
sprintf('the number of columns: %d', dim(df)[2])
[1] "the number of columns: 11"
# check missing values & nan
is.null(df)
[1] FALSE
colSums(is.na(df))
                    title                    author                    school            sentence_spacy 
                        0                         0                         0                         0 
             sentence_str original_publication_date       corpus_edition_date           sentence_length 
                        0                         0                         0                         0 
         sentence_lowered             tokenized_txt            lemmatized_str 
                        0                         0                         0 
# remove duplicated rows
df <- df[!duplicated(df), ]

EDA

The EDA of this project focus on exploring 5 of the 11 variables (title, author, school, original_publication_date, corpus_edition_date). The number of distinct levels for each variable are summarized in the table below.

# general summary of data set ----
summary(df[,c('sentence_length','original_publication_date','corpus_edition_date')])
 sentence_length  original_publication_date corpus_edition_date
 Min.   :  20.0   Min.   :-350              Min.   :1887       
 1st Qu.:  75.0   1st Qu.:1641              1st Qu.:1991       
 Median : 127.0   Median :1817              Median :2001       
 Mean   : 150.8   Mean   :1327              Mean   :1995       
 3rd Qu.: 199.0   3rd Qu.:1949              3rd Qu.:2007       
 Max.   :2649.0   Max.   :1985              Max.   :2016       
# summary of distinct values for each variables 
sapply(df, function(x) n_distinct(x))
                    title                    author                    school            sentence_spacy 
                       59                        36                        13                    360808 
             sentence_str original_publication_date       corpus_edition_date           sentence_length 
                   360808                        48                        28                       971 
         sentence_lowered             tokenized_txt            lemmatized_str 
                   360780                    360381                    360726 
df_noticed <- df[,c('title','author','school','original_publication_date','corpus_edition_date')]
# apply(): 1: rows & 2: columns
df_noticed_summary <- apply(df_noticed, MARGIN = 2, FUN = table) 

Title

# dataframe for unique values
title <- data.frame('title' = names(df_noticed_summary$title), 
                   'value' = unname(df_noticed_summary$title))
# top 10 frequency
title <- title %>% 
  select(title, value.Freq) %>%
  group_by(title) %>%
  arrange(desc(value.Freq))
head(title, 10)
# histogram for density 
plot_title <-
  ggplot(title, aes(x = reorder(title,-value.Freq), y = value.Freq)) + 
  geom_col(width = 0.8, fill = 'darkturquoise') + 
  labs(x = "title",y = "count") +
  ggtitle("Frequency of titles") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5))
plot_title

Author

author <- data.frame('author' = names(df_noticed_summary$author), 'value' = unname(df_noticed_summary$author))
author <- author %>% select(author, value.Freq) %>% group_by(author) %>% arrange(desc(value.Freq))
head(author, 10)
plot_author <- ggplot(author, aes(x = reorder(author,-value.Freq), y = value.Freq)) + geom_col(width = 0.8, fill = 'darkturquoise') + labs(x = "author",y = "count") + ggtitle("Frequency of authors") + theme(axis.text.x = element_text(angle = 90,hjust = 1,vjust = 0.5))
plot_author

School

school <- data.frame('school' = names(df_noticed_summary$school), 'value' = unname(df_noticed_summary$school))
school <- school %>% select(school, value.Freq) %>% group_by(school) %>% arrange(desc(value.Freq))
head(school, 10)
plot_school <- ggplot(school, aes(x = reorder(school,-value.Freq), y = value.Freq)) + geom_col(width = 0.8, fill = 'darkturquoise') + labs(x = "school",y = "count") + ggtitle("Frequency of schools") + theme(axis.text.x = element_text(angle = 90,hjust = 1,vjust = 0.5))
plot_school

Original publication date & Corpus edition date

publication <- data.frame('year' = names(df_noticed_summary$original_publication_date), 
                   'value' = unname(df_noticed_summary$original_publication_date),
                   'type' = 'publication')
edition <- data.frame('year' = names(df_noticed_summary$corpus_edition_date), 
                   'value' = unlist(unname(df_noticed_summary$corpus_edition_date)), 
                   'type' = 'edition')

timeline <- rbind(publication, edition) 
timeline <- timeline %>%
  select(year,value.Freq,type) 
# publication vs. edition plot ----
plot_timeline <- ggplot(timeline, aes(x = year, y = value.Freq, color = type)) + 
  geom_point() +
  stat_smooth(aes(group = 1), se = FALSE) +
  labs(x = "year",y = "count") + ggtitle("publication & edition over time") +
  scale_x_discrete(breaks = c(1637, 1710, 1807, 1907,1970, 2001))
plot_timeline

Summary tree diagram for school, author & title

#### create dataset for tree diagram ----
dat <- df[,c('school','author','title')]

test <- data.frame('id' = 'school', 'label' = 'school', 'parent' = '')
A = data.frame()
B = list()
C = list()
for(i in 1:length(unique(dat$school))) {
  A[i,'parent'] = 'school'
  filter1 = unique(dat$school)[i]
  A[i,'id'] = filter1
  A[i,'label'] = filter1
  # filter 2nd dataset for author
  B[[filter1]] <- unique(dat[dat$school == filter1, ]$author)
  }
for (j in 1:length(unique(dat$author))){
  # filter 3rd dataset for title
  filter2 = unique(dat$author)[j]
  C[[filter2]] <- unique(dat[dat$author == filter2, ]$title)
  }
# edit list B,C to dataframe
B <- stack(B) %>% mutate('label' = values) %>% rename( 'id' = 'values','parent' = 'ind')
C <- stack(C) %>% mutate('label' = values) %>% rename( 'id' = 'values','parent' = 'ind')
test <- bind_rows(test, A, B, C)

#### plot tree diagram ----
fig <- plot_ly(
  type = 'treemap',
  ids = test$id,
  labels = test$label,
  parents = test$parent)
fig <- fig %>% 
  layout(uniformtext = list(minsize=10, mode='hide')) %>% 
  layout(title = 'tree diagram for school, author & title')
fig

Capitalism analysis

Why Capitalism?

As said on COLUMBIA STUDIES IN THE HISTORY OF U.S. CAPITALISM, “Capitalism has served as an engine of growth, a source of inequality, and a catalyst for conflict in American history”, the capitalism has a great impact on the American society. By exploring the words of the philosophers of capitalism, we might have a better understanding of how capitalism related to the American society & people, and wonder if the idea of capitalism changes over time. The 3 represents of capitalism included in this dataset are John Maynard Keynes, David Ricardo & Adam Smith.

English economist, one of the most influential economists of the 20th century. His ideas fundamentally changed the theory and practice of macroeconomics & the economic policies of governments.

British political economist, an abolitionist, one of the most influential of the classical economists. As the Napoleonic Wars waged on, David Ricardo developed a disdain for the Corn Laws imposed by the British to encourage exports.

Scottish economist & philosopher who was also known as “The Father of Economics”. One of his great works, “The Wealth Of Nations” is used to reflect his thought in this project.

capitalism <- filter(df, author %in% c('Smith','Ricardo','Keynes'))
Keynes <- filter(df,author == 'Keynes')
Ricardo <- filter(df, author == 'Ricardo')
Smith <- filter(df, author == 'Smith')

Word cloud for capitalism

# data table prepare
# import data as a corpus
word_tot <- Corpus(VectorSource(capitalism$sentence_lowered))
word_tot <- tm_map(word_tot, stripWhitespace)
word_tot <- tm_map(word_tot, content_transformer(tolower))
word_tot <- tm_map(word_tot, removeWords, stopwords("english"))
word_tot <- tm_map(word_tot, removeWords, character(0))
word_tot <- tm_map(word_tot, removePunctuation)
word_tot <- tm_map(word_tot, removeNumbers)
dword_tot <- TermDocumentMatrix(word_tot)
mword_tot <- as.matrix(dword_tot)
sort <- sort(rowSums(mword_tot),decreasing = TRUE)
dt_tot <- data.frame(word = names(sort),freq = sort)
# word cloud plot
wordcloud(words = dt_tot$word, freq = dt_tot$freq,
          scale = c(4,0.5),
          min.freq = 1,
          max.words = 200, 
          random.order = FALSE, 
          rot.per = 0.35, 
          colors = brewer.pal(8, "Dark2"))

Sentence_length variation

source("/Users/sherry/Documents/Github/fall2022-project1-YudanZhang/lib/boxplot_stats.R")
plot_sentence_length <- ggplot(data = capitalism, aes(x = author, y = sentence_length)) +
  geom_boxplot(aes(fill = author)) +
  stat_summary(fun.data = boxplot_stats, geom = "text", hjust = 0.5, vjust = 1) +
  labs(x = "capitalism author",y = "Sentence length") +
  ggtitle("Boxplots of sentence_length variation by capitalism authors") 
plot_sentence_length

Comparison of top 10 frequent words

#### Keynes word cloud ----
word_K <- Corpus(VectorSource(Keynes$sentence_lowered))
word_K <- tm_map(word_K, stripWhitespace)
word_K <- tm_map(word_K, content_transformer(tolower))
word_K <- tm_map(word_K, removeWords, stopwords("english"))
word_K <- tm_map(word_K, removeWords, character(0))
word_K <- tm_map(word_K, removePunctuation)
word_K <- tm_map(word_K, removeNumbers)
dword_K <- TermDocumentMatrix(word_K)
mword_K <- as.matrix(dword_K)
sort <- sort(rowSums(mword_K),decreasing = TRUE)
dt_K <- data.frame(word = names(sort),freq = sort)
# head(dt_K, 10)
#### Ricardo word cloud ----
word_R <- Corpus(VectorSource(Ricardo$sentence_lowered))
word_R <- tm_map(word_R, stripWhitespace)
word_R <- tm_map(word_R, content_transformer(tolower))
word_R <- tm_map(word_R, removeWords, stopwords("english"))
word_R <- tm_map(word_R, removeWords, character(0))
word_R <- tm_map(word_R, removePunctuation)
word_R <- tm_map(word_R, removeNumbers)
dword_R <- TermDocumentMatrix(word_R)
mword_R <- as.matrix(dword_R)
sort <- sort(rowSums(mword_R),decreasing = TRUE)
dt_R <- data.frame(word = names(sort),freq = sort)
#### Smith word cloud ----
word_S <- Corpus(VectorSource(Smith$sentence_lowered))
word_S <- tm_map(word_S, stripWhitespace)
word_S <- tm_map(word_S, content_transformer(tolower))
word_S <- tm_map(word_S, removeWords, stopwords("english"))
word_S <- tm_map(word_S, removeWords, character(0))
word_S <- tm_map(word_S, removePunctuation)
word_S <- tm_map(word_S, removeNumbers)
dword_S <- TermDocumentMatrix(word_S)
mword_S <- as.matrix(dword_S)
sort <- sort(rowSums(mword_S),decreasing = TRUE)
dt_S <- data.frame(word = names(sort),freq = sort)
### comparison of top 10 frequent words ----
plot_K <- ggplot(dt_K[1:10,], aes(x = reorder(word,-freq),y = freq)) + geom_col(fill = 'coral1') + geom_text(aes(label = freq), vjust = -0.5) + labs(x = "Word", y = "Count") + ggtitle("Keynes") 
plot_R <- ggplot(dt_R[1:10,], aes(x = reorder(word,-freq),y = freq)) + geom_col(fill = 'chartreuse1') + geom_text(aes(label = freq), vjust = -0.5) + labs(x = "Word") + ggtitle("Ricardo") + theme(axis.title.y = element_blank())
plot_S <- ggplot(dt_S[1:10,], aes(x = reorder(word,-freq),y = freq)) + geom_col(fill = 'darkturquoise') + geom_text(aes(label = freq), vjust = -0.5) + labs(x = "Word") + ggtitle("Smith") + theme(axis.title.y = element_blank())
grid.arrange(plot_K, plot_R, plot_S, ncol = 1, top = "comparison of top 10 frequent words by author") 

Noticed the “corn” word shown in the Ricardo frequent word, it supports the fact that he concerned the Corn Laws imposed by the British government.

Sentiment analysis

#### Keynes ----
emo_K <- get_nrc_sentiment(Keynes$sentence_lowered)
result_K <- data.frame(t(emo_K))
#rowSums computes column sums across rows for each level of a grouping variable.
new_result_K <- data.frame(rowSums(result_K))
#name rows and columns of the dataframe
names(new_result_K)[1] <- "count"
new_result_K <- cbind("sentiment" = rownames(new_result_K), new_result_K)
rownames(new_result_K) <- NULL
# plot 
slices_K <- new_result_K[1:8,"count"]
lbls_K <- paste(new_result_K$sentiment, round(slices_K/sum(slices_K)*100), "%", sep = "")

#### Ricardo ----
emo_R <- get_nrc_sentiment(Ricardo$sentence_lowered)
par(mfrow = c(1,3))
pie(x = slices_K, label = lbls_K, col = rainbow(length(lbls_K)), main = "emotion pie chart of Keynes")
pie(x = slices_R, label = lbls_R, col = rainbow(length(lbls_R)), main = "emotion pie chart of Ricardo")
pie(x = slices_S, label = lbls_S, col = rainbow(length(lbls_S)), main = "emotion pie chart of Smith")

Conclusion

There is a lot of similarity between Keynes, Ricardo & Smith such as the average sentence length & emotional tone (trust > anticipation > joy > sadness / anger / fear) in their works.

Even though the frequent words are not really in common, they both talked about money, commodities, and the country and labour. The former is the core of the market economy (just like the economic system of the United States) and the latter are the keywords in the political field. As shown in the analysis of emotion, even though they were born at different times, their passion for capitalist philosophy is the same.

LS0tCnRpdGxlOiAiUHJvamVjdDE6IFIgTm90ZWJvb2sgUGhpbG9zb3BoeSBEYXRhIFN0b3J5IgphdXRob3I6ICJZdWRhbiBaaGFuZyIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQojIFByb2plY3QxIEludHJvZHVjdGlvbjogCgpUaGUgZ29hbCBvZiB0aGlzIHByb2plY3QxIGlzIGdvaW5nIHRvIHByb3ZpZGUgYW5hbHlzaXMgbWFpbmx5IG9uIDMgYXV0aG9ycyAoS2V5bmVzLCBSaWNhcmRvLCBTbWl0aCkgZnJvbSBjYXBpdGFsaXNtLiAKCiMjIyBPdXRsaW5lIG9mIHByb2plY3QKCiAqIFBhY2thZ2VzIGxvYWRpbmcKICogRGF0YSBlZGl0ICYgY2xlYW4gCiAqIEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMgKEVEQSkKICAgICArIFRpdGxlCiAgICAgKyBBdXRob3IKICAgICArIFNjaG9vbAogICAgICsgT3JpZ2luYWwgcHVibGljYXRpb24gZGF0ZSAmIENvcnB1cyBlZGl0aW9uIGRhdGUKICAgICArIFN1bW1hcnkgdHJlZSBkaWFncmFtIGZvciBzY2hvb2wsIGF1dGhvciAmIHRpdGxlIAoKICogQW5hbHlzaXMgb2YgY2FwaXRhbGlzbQogICAgICsgIFdoeSBDYXBpdGFsaXNtID8KICAgICArICBXb3JkIGNsb3VkIGZvciBjYXBpdGFsaXNtCiAgICAgKyAgU2VudGVuY2VfbGVuZ3RoIHZhcmlhdGlvbiBieSBhdXRob3IKICAgICArICBDb21wYXJpc29uIG9mIHRvcCAxMCBmcmVxdWVudCB3b3JkcyBieSBhdXRob3IKICAgICAKICAqIEFuYWx5c2lzIG9mIHNlbnRpbWVudCAKICAgICArIEtleW5lcwogICAgICsgUmljYXJkbwogICAgICsgU2ltaXRoCiAgCiAgKiBDb25jbHVzaW9uCgojIyBQYWNrYWdlcyBsb2FkaW5nCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwbG90bHkpICMgdHJlZSBkaWFncmFtIApsaWJyYXJ5KHRtKQojIHdvcmQgY2xvdWQKbGlicmFyeSh3b3JkY2xvdWQpCmxpYnJhcnkoUkNvbG9yQnJld2VyKQpsaWJyYXJ5KFNub3diYWxsQykKbGlicmFyeShncmlkRXh0cmEpICMgYXJyYW5nZSBwbG90IGZvciBzZW50ZW5jZV9sZW5ndGggY29tcGFyaXNvbgpsaWJyYXJ5KHN5dXpoZXQpICMgc2VudGltZW50IGFuYWx5c2lzCmBgYAoKIyMgRGF0ZSBFZGl0ICYgQ2xlYW4KClRoZXJlIGFyZSAzNjA4MDggb2JzZXJ2YXRpb25zIHdpdGggMTEgdmFyaWFibGVzICh0aXRsZSwgYXV0aG9yLCBzY2hvb2wsIHNlbnRlbmNlX3NwYWN5LCBzZW50ZW5jZV9zdHIsIG9yaWdpbmFsX3B1YmxpY2F0aW9uX2RhdGUsIGNvcnB1c19lZGl0aW9uX2RhdGUsIHNlbnRlbmNlX2xlbmd0aCwgc2VudGVuY2VfbG93ZXJlZCwgdG9rZW5pemVkX3R4dCwgbGVtbWF0aXplZF9zdHIpIGluIHRoaXMgZGF0YXNldC4gT25seSAxIG51bWVyaWMgdmFyaWFibGUgKHNlbnRlbmNlX2xlbmd0aCksIDIgdGltZSB2YXJpYWJsZXMgKG9yaWdpbmFsX3B1YmxpY2F0aW9uX2RhdGUsIGNvcnB1c19lZGl0aW9uX2RhdGUpLCBhbmQgdGhlIHJlc3QgYXJlIGNoYXJhY3RlciB2YXJpYWJsZXMuIE5vIG1pc3NpbmcgdmFsdWVzIC8gJ25hbicgZXhpc3RzIGZvciBlYWNoIHZhcmlhYmxlIGFuZCBubyBkdXBsaWNhdGVkIG9ic2VydmF0aW9ucyBpbiB0aGUgZGF0YXNldC4gCgpgYGB7cn0KZGYgPSByZWFkLmNzdignL1VzZXJzL3NoZXJyeS9Eb2N1bWVudHMvR2l0aHViL2ZhbGwyMDIyLXByb2plY3QxLVl1ZGFuWmhhbmcvZGF0YS9waGlsb3NvcGh5X2RhdGEuY3N2JykKaGVhZChkZikKYGBgCgpgYGB7ciB3YXJuaW5nPUZBTFNFfQpzcHJpbnRmKCd0aGUgbnVtYmVyIG9mIHJvd3M6ICVkJywgZGltKGRmKVsxXSkKc3ByaW50ZigndGhlIG51bWJlciBvZiBjb2x1bW5zOiAlZCcsIGRpbShkZilbMl0pCiMgY2hlY2sgbWlzc2luZyB2YWx1ZXMgJiBuYW4KaXMubnVsbChkZikKY29sU3Vtcyhpcy5uYShkZikpCiMgcmVtb3ZlIGR1cGxpY2F0ZWQgcm93cwpkZiA8LSBkZlshZHVwbGljYXRlZChkZiksIF0KYGBgCgojIyBFREEgCgpUaGUgRURBIG9mIHRoaXMgcHJvamVjdCBmb2N1cyBvbiBleHBsb3JpbmcgNSBvZiB0aGUgMTEgdmFyaWFibGVzICh0aXRsZSwgYXV0aG9yLCBzY2hvb2wsIG9yaWdpbmFsX3B1YmxpY2F0aW9uX2RhdGUsIGNvcnB1c19lZGl0aW9uX2RhdGUpLiBUaGUgbnVtYmVyIG9mIGRpc3RpbmN0IGxldmVscyBmb3IgZWFjaCB2YXJpYWJsZSBhcmUgc3VtbWFyaXplZCBpbiB0aGUgdGFibGUgYmVsb3cuIAoKYGBge3Igd2FybmluZz1GQUxTRX0KIyBnZW5lcmFsIHN1bW1hcnkgb2YgZGF0YSBzZXQgLS0tLQpzdW1tYXJ5KGRmWyxjKCdzZW50ZW5jZV9sZW5ndGgnLCdvcmlnaW5hbF9wdWJsaWNhdGlvbl9kYXRlJywnY29ycHVzX2VkaXRpb25fZGF0ZScpXSkKIyBzdW1tYXJ5IG9mIGRpc3RpbmN0IHZhbHVlcyBmb3IgZWFjaCB2YXJpYWJsZXMgCnNhcHBseShkZiwgZnVuY3Rpb24oeCkgbl9kaXN0aW5jdCh4KSkKZGZfbm90aWNlZCA8LSBkZlssYygndGl0bGUnLCdhdXRob3InLCdzY2hvb2wnLCdvcmlnaW5hbF9wdWJsaWNhdGlvbl9kYXRlJywnY29ycHVzX2VkaXRpb25fZGF0ZScpXQojIGFwcGx5KCk6IDE6IHJvd3MgJiAyOiBjb2x1bW5zCmRmX25vdGljZWRfc3VtbWFyeSA8LSBhcHBseShkZl9ub3RpY2VkLCBNQVJHSU4gPSAyLCBGVU4gPSB0YWJsZSkgCmBgYAoKIyMjIFRpdGxlIAoKYGBge3Igd2FybmluZz1GQUxTRX0KIyBkYXRhZnJhbWUgZm9yIHVuaXF1ZSB2YWx1ZXMKdGl0bGUgPC0gZGF0YS5mcmFtZSgndGl0bGUnID0gbmFtZXMoZGZfbm90aWNlZF9zdW1tYXJ5JHRpdGxlKSwgCiAgICAgICAgICAgICAgICAgICAndmFsdWUnID0gdW5uYW1lKGRmX25vdGljZWRfc3VtbWFyeSR0aXRsZSkpCiMgdG9wIDEwIGZyZXF1ZW5jeQp0aXRsZSA8LSB0aXRsZSAlPiUgCiAgc2VsZWN0KHRpdGxlLCB2YWx1ZS5GcmVxKSAlPiUKICBncm91cF9ieSh0aXRsZSkgJT4lCiAgYXJyYW5nZShkZXNjKHZhbHVlLkZyZXEpKQpoZWFkKHRpdGxlLCAxMCkKIyBoaXN0b2dyYW0gZm9yIGRlbnNpdHkgCnBsb3RfdGl0bGUgPC0KICBnZ3Bsb3QodGl0bGUsIGFlcyh4ID0gcmVvcmRlcih0aXRsZSwtdmFsdWUuRnJlcSksIHkgPSB2YWx1ZS5GcmVxKSkgKyAKICBnZW9tX2NvbCh3aWR0aCA9IDAuOCwgZmlsbCA9ICdkYXJrdHVycXVvaXNlJykgKyAKICBsYWJzKHggPSAidGl0bGUiLHkgPSAiY291bnQiKSArCiAgZ2d0aXRsZSgiRnJlcXVlbmN5IG9mIHRpdGxlcyIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEsIHZqdXN0ID0gMC41KSkKcGxvdF90aXRsZQpgYGAKCiMjIyBBdXRob3IgCgpgYGB7cn0KYXV0aG9yIDwtIGRhdGEuZnJhbWUoJ2F1dGhvcicgPSBuYW1lcyhkZl9ub3RpY2VkX3N1bW1hcnkkYXV0aG9yKSwgJ3ZhbHVlJyA9IHVubmFtZShkZl9ub3RpY2VkX3N1bW1hcnkkYXV0aG9yKSkKYXV0aG9yIDwtIGF1dGhvciAlPiUgc2VsZWN0KGF1dGhvciwgdmFsdWUuRnJlcSkgJT4lIGdyb3VwX2J5KGF1dGhvcikgJT4lIGFycmFuZ2UoZGVzYyh2YWx1ZS5GcmVxKSkKaGVhZChhdXRob3IsIDEwKQpwbG90X2F1dGhvciA8LSBnZ3Bsb3QoYXV0aG9yLCBhZXMoeCA9IHJlb3JkZXIoYXV0aG9yLC12YWx1ZS5GcmVxKSwgeSA9IHZhbHVlLkZyZXEpKSArIGdlb21fY29sKHdpZHRoID0gMC44LCBmaWxsID0gJ2Rhcmt0dXJxdW9pc2UnKSArIGxhYnMoeCA9ICJhdXRob3IiLHkgPSAiY291bnQiKSArIGdndGl0bGUoIkZyZXF1ZW5jeSBvZiBhdXRob3JzIikgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLGhqdXN0ID0gMSx2anVzdCA9IDAuNSkpCnBsb3RfYXV0aG9yCmBgYAoKIyMjIFNjaG9vbAoKYGBge3J9CnNjaG9vbCA8LSBkYXRhLmZyYW1lKCdzY2hvb2wnID0gbmFtZXMoZGZfbm90aWNlZF9zdW1tYXJ5JHNjaG9vbCksICd2YWx1ZScgPSB1bm5hbWUoZGZfbm90aWNlZF9zdW1tYXJ5JHNjaG9vbCkpCnNjaG9vbCA8LSBzY2hvb2wgJT4lIHNlbGVjdChzY2hvb2wsIHZhbHVlLkZyZXEpICU+JSBncm91cF9ieShzY2hvb2wpICU+JSBhcnJhbmdlKGRlc2ModmFsdWUuRnJlcSkpCmhlYWQoc2Nob29sLCAxMCkKcGxvdF9zY2hvb2wgPC0gZ2dwbG90KHNjaG9vbCwgYWVzKHggPSByZW9yZGVyKHNjaG9vbCwtdmFsdWUuRnJlcSksIHkgPSB2YWx1ZS5GcmVxKSkgKyBnZW9tX2NvbCh3aWR0aCA9IDAuOCwgZmlsbCA9ICdkYXJrdHVycXVvaXNlJykgKyBsYWJzKHggPSAic2Nob29sIix5ID0gImNvdW50IikgKyBnZ3RpdGxlKCJGcmVxdWVuY3kgb2Ygc2Nob29scyIpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCxoanVzdCA9IDEsdmp1c3QgPSAwLjUpKQpwbG90X3NjaG9vbApgYGAKCiMjIyBPcmlnaW5hbCBwdWJsaWNhdGlvbiBkYXRlICYgQ29ycHVzIGVkaXRpb24gZGF0ZQoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KcHVibGljYXRpb24gPC0gZGF0YS5mcmFtZSgneWVhcicgPSBuYW1lcyhkZl9ub3RpY2VkX3N1bW1hcnkkb3JpZ2luYWxfcHVibGljYXRpb25fZGF0ZSksIAogICAgICAgICAgICAgICAgICAgJ3ZhbHVlJyA9IHVubmFtZShkZl9ub3RpY2VkX3N1bW1hcnkkb3JpZ2luYWxfcHVibGljYXRpb25fZGF0ZSksCiAgICAgICAgICAgICAgICAgICAndHlwZScgPSAncHVibGljYXRpb24nKQplZGl0aW9uIDwtIGRhdGEuZnJhbWUoJ3llYXInID0gbmFtZXMoZGZfbm90aWNlZF9zdW1tYXJ5JGNvcnB1c19lZGl0aW9uX2RhdGUpLCAKICAgICAgICAgICAgICAgICAgICd2YWx1ZScgPSB1bmxpc3QodW5uYW1lKGRmX25vdGljZWRfc3VtbWFyeSRjb3JwdXNfZWRpdGlvbl9kYXRlKSksIAogICAgICAgICAgICAgICAgICAgJ3R5cGUnID0gJ2VkaXRpb24nKQoKdGltZWxpbmUgPC0gcmJpbmQocHVibGljYXRpb24sIGVkaXRpb24pIAp0aW1lbGluZSA8LSB0aW1lbGluZSAlPiUKICBzZWxlY3QoeWVhcix2YWx1ZS5GcmVxLHR5cGUpIAojIHB1YmxpY2F0aW9uIHZzLiBlZGl0aW9uIHBsb3QgLS0tLQpwbG90X3RpbWVsaW5lIDwtIGdncGxvdCh0aW1lbGluZSwgYWVzKHggPSB5ZWFyLCB5ID0gdmFsdWUuRnJlcSwgY29sb3IgPSB0eXBlKSkgKyAKICBnZW9tX3BvaW50KCkgKwogIHN0YXRfc21vb3RoKGFlcyhncm91cCA9IDEpLCBzZSA9IEZBTFNFKSArCiAgbGFicyh4ID0gInllYXIiLHkgPSAiY291bnQiKSArIGdndGl0bGUoInB1YmxpY2F0aW9uICYgZWRpdGlvbiBvdmVyIHRpbWUiKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShicmVha3MgPSBjKDE2MzcsIDE3MTAsIDE4MDcsIDE5MDcsMTk3MCwgMjAwMSkpCnBsb3RfdGltZWxpbmUKYGBgCgojIyMgU3VtbWFyeSB0cmVlIGRpYWdyYW0gZm9yIHNjaG9vbCwgYXV0aG9yICYgdGl0bGUgCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMjIGNyZWF0ZSBkYXRhc2V0IGZvciB0cmVlIGRpYWdyYW0gLS0tLQpkYXQgPC0gZGZbLGMoJ3NjaG9vbCcsJ2F1dGhvcicsJ3RpdGxlJyldCgp0ZXN0IDwtIGRhdGEuZnJhbWUoJ2lkJyA9ICdzY2hvb2wnLCAnbGFiZWwnID0gJ3NjaG9vbCcsICdwYXJlbnQnID0gJycpCkEgPSBkYXRhLmZyYW1lKCkKQiA9IGxpc3QoKQpDID0gbGlzdCgpCmZvcihpIGluIDE6bGVuZ3RoKHVuaXF1ZShkYXQkc2Nob29sKSkpIHsKICBBW2ksJ3BhcmVudCddID0gJ3NjaG9vbCcKICBmaWx0ZXIxID0gdW5pcXVlKGRhdCRzY2hvb2wpW2ldCiAgQVtpLCdpZCddID0gZmlsdGVyMQogIEFbaSwnbGFiZWwnXSA9IGZpbHRlcjEKICAjIGZpbHRlciAybmQgZGF0YXNldCBmb3IgYXV0aG9yCiAgQltbZmlsdGVyMV1dIDwtIHVuaXF1ZShkYXRbZGF0JHNjaG9vbCA9PSBmaWx0ZXIxLCBdJGF1dGhvcikKICB9CmZvciAoaiBpbiAxOmxlbmd0aCh1bmlxdWUoZGF0JGF1dGhvcikpKXsKICAjIGZpbHRlciAzcmQgZGF0YXNldCBmb3IgdGl0bGUKICBmaWx0ZXIyID0gdW5pcXVlKGRhdCRhdXRob3IpW2pdCiAgQ1tbZmlsdGVyMl1dIDwtIHVuaXF1ZShkYXRbZGF0JGF1dGhvciA9PSBmaWx0ZXIyLCBdJHRpdGxlKQogIH0KIyBlZGl0IGxpc3QgQixDIHRvIGRhdGFmcmFtZQpCIDwtIHN0YWNrKEIpICU+JSBtdXRhdGUoJ2xhYmVsJyA9IHZhbHVlcykgJT4lIHJlbmFtZSggJ2lkJyA9ICd2YWx1ZXMnLCdwYXJlbnQnID0gJ2luZCcpCkMgPC0gc3RhY2soQykgJT4lIG11dGF0ZSgnbGFiZWwnID0gdmFsdWVzKSAlPiUgcmVuYW1lKCAnaWQnID0gJ3ZhbHVlcycsJ3BhcmVudCcgPSAnaW5kJykKdGVzdCA8LSBiaW5kX3Jvd3ModGVzdCwgQSwgQiwgQykKCiMjIyMgcGxvdCB0cmVlIGRpYWdyYW0gLS0tLQpmaWcgPC0gcGxvdF9seSgKICB0eXBlID0gJ3RyZWVtYXAnLAogIGlkcyA9IHRlc3QkaWQsCiAgbGFiZWxzID0gdGVzdCRsYWJlbCwKICBwYXJlbnRzID0gdGVzdCRwYXJlbnQpCmZpZyA8LSBmaWcgJT4lIAogIGxheW91dCh1bmlmb3JtdGV4dCA9IGxpc3QobWluc2l6ZT0xMCwgbW9kZT0naGlkZScpKSAlPiUgCiAgbGF5b3V0KHRpdGxlID0gJ3RyZWUgZGlhZ3JhbSBmb3Igc2Nob29sLCBhdXRob3IgJiB0aXRsZScpCmZpZwpgYGAKCiMjIENhcGl0YWxpc20gYW5hbHlzaXMgCgojIyMgV2h5IENhcGl0YWxpc20/CgpBcyBzYWlkIG9uIFtDT0xVTUJJQSBTVFVESUVTIElOIFRIRSBISVNUT1JZIE9GIFUuUy4gQ0FQSVRBTElTTV0oaHR0cHM6Ly9jdXAuY29sdW1iaWEuZWR1L2hvYyksICJDYXBpdGFsaXNtIGhhcyBzZXJ2ZWQgYXMgYW4gZW5naW5lIG9mIGdyb3d0aCwgYSBzb3VyY2Ugb2YgaW5lcXVhbGl0eSwgYW5kIGEgY2F0YWx5c3QgZm9yIGNvbmZsaWN0IGluIEFtZXJpY2FuIGhpc3RvcnkiLCB0aGUgY2FwaXRhbGlzbSBoYXMgYSBncmVhdCBpbXBhY3Qgb24gdGhlIEFtZXJpY2FuIHNvY2lldHkuIEJ5IGV4cGxvcmluZyB0aGUgd29yZHMgb2YgdGhlIHBoaWxvc29waGVycyBvZiBjYXBpdGFsaXNtLCB3ZSBtaWdodCBoYXZlIGEgYmV0dGVyIHVuZGVyc3RhbmRpbmcgb2YgaG93IGNhcGl0YWxpc20gcmVsYXRlZCB0byB0aGUgQW1lcmljYW4gc29jaWV0eSAmIHBlb3BsZSwgYW5kIHdvbmRlciBpZiB0aGUgaWRlYSBvZiBjYXBpdGFsaXNtIGNoYW5nZXMgb3ZlciB0aW1lLiBUaGUgMyByZXByZXNlbnRzIG9mIGNhcGl0YWxpc20gaW5jbHVkZWQgaW4gdGhpcyBkYXRhc2V0IGFyZSBKb2huIE1heW5hcmQgS2V5bmVzLCBEYXZpZCBSaWNhcmRvICYgQWRhbSBTbWl0aC4KCiAqIFtKb2huIE1heW5hcmQgS2V5bmVzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Kb2huX01heW5hcmRfS2V5bmVzKSAoMDUgSnVuZSAxODgzIOKAkyAyMSBBcHJpbCAxOTQ2KQoKRW5nbGlzaCBlY29ub21pc3QsIG9uZSBvZiB0aGUgbW9zdCBpbmZsdWVudGlhbCBlY29ub21pc3RzIG9mIHRoZSAyMHRoIGNlbnR1cnkuIEhpcyBpZGVhcyBmdW5kYW1lbnRhbGx5IGNoYW5nZWQgdGhlIHRoZW9yeSBhbmQgcHJhY3RpY2Ugb2YgbWFjcm9lY29ub21pY3MgJiB0aGUgZWNvbm9taWMgcG9saWNpZXMgb2YgZ292ZXJubWVudHMuIAoKICogW0RhdmlkIFJpY2FyZG9dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0RhdmlkX1JpY2FyZG8pICgxOCBBcHJpbCAxNzcyIOKAkyAxMSBTZXB0ZW1iZXIgMTgyMykKIApCcml0aXNoIHBvbGl0aWNhbCBlY29ub21pc3QsIGFuIGFib2xpdGlvbmlzdCwgb25lIG9mIHRoZSBtb3N0IGluZmx1ZW50aWFsIG9mIHRoZSBjbGFzc2ljYWwgZWNvbm9taXN0cy4gQXMgdGhlIE5hcG9sZW9uaWMgV2FycyB3YWdlZCBvbiwgRGF2aWQgUmljYXJkbyBkZXZlbG9wZWQgYSBkaXNkYWluIGZvciB0aGUgQ29ybiBMYXdzIGltcG9zZWQgYnkgdGhlIEJyaXRpc2ggdG8gZW5jb3VyYWdlIGV4cG9ydHMuCgogKiBbQWRhbSBTbWl0aF0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQWRhbV9TbWl0aCkgKDE2IEp1bmUgMTcyMyDigJMgMTcgSnVseSAxNzkwKSAKIApTY290dGlzaCBlY29ub21pc3QgJiBwaGlsb3NvcGhlciB3aG8gd2FzIGFsc28ga25vd24gYXMgIlRoZSBGYXRoZXIgb2YgRWNvbm9taWNzIi4gT25lIG9mIGhpcyBncmVhdCB3b3JrcywgIlRoZSBXZWFsdGggT2YgTmF0aW9ucyIgaXMgdXNlZCB0byByZWZsZWN0IGhpcyB0aG91Z2h0IGluIHRoaXMgcHJvamVjdC4gCiAKYGBge3J9CmNhcGl0YWxpc20gPC0gZmlsdGVyKGRmLCBhdXRob3IgJWluJSBjKCdTbWl0aCcsJ1JpY2FyZG8nLCdLZXluZXMnKSkKS2V5bmVzIDwtIGZpbHRlcihkZixhdXRob3IgPT0gJ0tleW5lcycpClJpY2FyZG8gPC0gZmlsdGVyKGRmLCBhdXRob3IgPT0gJ1JpY2FyZG8nKQpTbWl0aCA8LSBmaWx0ZXIoZGYsIGF1dGhvciA9PSAnU21pdGgnKQpgYGAKCiMjIyBXb3JkIGNsb3VkIGZvciBjYXBpdGFsaXNtCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIGRhdGEgdGFibGUgcHJlcGFyZQojIGltcG9ydCBkYXRhIGFzIGEgY29ycHVzCndvcmRfdG90IDwtIENvcnB1cyhWZWN0b3JTb3VyY2UoY2FwaXRhbGlzbSRzZW50ZW5jZV9sb3dlcmVkKSkKd29yZF90b3QgPC0gdG1fbWFwKHdvcmRfdG90LCBzdHJpcFdoaXRlc3BhY2UpCndvcmRfdG90IDwtIHRtX21hcCh3b3JkX3RvdCwgY29udGVudF90cmFuc2Zvcm1lcih0b2xvd2VyKSkKd29yZF90b3QgPC0gdG1fbWFwKHdvcmRfdG90LCByZW1vdmVXb3Jkcywgc3RvcHdvcmRzKCJlbmdsaXNoIikpCndvcmRfdG90IDwtIHRtX21hcCh3b3JkX3RvdCwgcmVtb3ZlV29yZHMsIGNoYXJhY3RlcigwKSkKd29yZF90b3QgPC0gdG1fbWFwKHdvcmRfdG90LCByZW1vdmVQdW5jdHVhdGlvbikKd29yZF90b3QgPC0gdG1fbWFwKHdvcmRfdG90LCByZW1vdmVOdW1iZXJzKQpkd29yZF90b3QgPC0gVGVybURvY3VtZW50TWF0cml4KHdvcmRfdG90KQptd29yZF90b3QgPC0gYXMubWF0cml4KGR3b3JkX3RvdCkKc29ydCA8LSBzb3J0KHJvd1N1bXMobXdvcmRfdG90KSxkZWNyZWFzaW5nID0gVFJVRSkKZHRfdG90IDwtIGRhdGEuZnJhbWUod29yZCA9IG5hbWVzKHNvcnQpLGZyZXEgPSBzb3J0KQojIHdvcmQgY2xvdWQgcGxvdAp3b3JkY2xvdWQod29yZHMgPSBkdF90b3Qkd29yZCwgZnJlcSA9IGR0X3RvdCRmcmVxLAogICAgICAgICAgc2NhbGUgPSBjKDQsMC41KSwKICAgICAgICAgIG1pbi5mcmVxID0gMSwKICAgICAgICAgIG1heC53b3JkcyA9IDIwMCwgCiAgICAgICAgICByYW5kb20ub3JkZXIgPSBGQUxTRSwgCiAgICAgICAgICByb3QucGVyID0gMC4zNSwgCiAgICAgICAgICBjb2xvcnMgPSBicmV3ZXIucGFsKDgsICJEYXJrMiIpKQpgYGAKCiMjIyBTZW50ZW5jZV9sZW5ndGggdmFyaWF0aW9uIAoKYGBge3J9CnNvdXJjZSgiL1VzZXJzL3NoZXJyeS9Eb2N1bWVudHMvR2l0aHViL2ZhbGwyMDIyLXByb2plY3QxLVl1ZGFuWmhhbmcvbGliL2JveHBsb3Rfc3RhdHMuUiIpCnBsb3Rfc2VudGVuY2VfbGVuZ3RoIDwtIGdncGxvdChkYXRhID0gY2FwaXRhbGlzbSwgYWVzKHggPSBhdXRob3IsIHkgPSBzZW50ZW5jZV9sZW5ndGgpKSArCiAgZ2VvbV9ib3hwbG90KGFlcyhmaWxsID0gYXV0aG9yKSkgKwogIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IGJveHBsb3Rfc3RhdHMsIGdlb20gPSAidGV4dCIsIGhqdXN0ID0gMC41LCB2anVzdCA9IDEpICsKICBsYWJzKHggPSAiY2FwaXRhbGlzbSBhdXRob3IiLHkgPSAiU2VudGVuY2UgbGVuZ3RoIikgKwogIGdndGl0bGUoIkJveHBsb3RzIG9mIHNlbnRlbmNlX2xlbmd0aCB2YXJpYXRpb24gYnkgY2FwaXRhbGlzbSBhdXRob3JzIikgCnBsb3Rfc2VudGVuY2VfbGVuZ3RoCmBgYAoKIyMjIENvbXBhcmlzb24gb2YgdG9wIDEwIGZyZXF1ZW50IHdvcmRzIAoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyMjIyBLZXluZXMgd29yZCBjbG91ZCAtLS0tCndvcmRfSyA8LSBDb3JwdXMoVmVjdG9yU291cmNlKEtleW5lcyRzZW50ZW5jZV9sb3dlcmVkKSkKd29yZF9LIDwtIHRtX21hcCh3b3JkX0ssIHN0cmlwV2hpdGVzcGFjZSkKd29yZF9LIDwtIHRtX21hcCh3b3JkX0ssIGNvbnRlbnRfdHJhbnNmb3JtZXIodG9sb3dlcikpCndvcmRfSyA8LSB0bV9tYXAod29yZF9LLCByZW1vdmVXb3Jkcywgc3RvcHdvcmRzKCJlbmdsaXNoIikpCndvcmRfSyA8LSB0bV9tYXAod29yZF9LLCByZW1vdmVXb3JkcywgY2hhcmFjdGVyKDApKQp3b3JkX0sgPC0gdG1fbWFwKHdvcmRfSywgcmVtb3ZlUHVuY3R1YXRpb24pCndvcmRfSyA8LSB0bV9tYXAod29yZF9LLCByZW1vdmVOdW1iZXJzKQpkd29yZF9LIDwtIFRlcm1Eb2N1bWVudE1hdHJpeCh3b3JkX0spCm13b3JkX0sgPC0gYXMubWF0cml4KGR3b3JkX0spCnNvcnQgPC0gc29ydChyb3dTdW1zKG13b3JkX0spLGRlY3JlYXNpbmcgPSBUUlVFKQpkdF9LIDwtIGRhdGEuZnJhbWUod29yZCA9IG5hbWVzKHNvcnQpLGZyZXEgPSBzb3J0KQojIGhlYWQoZHRfSywgMTApCiMjIyMgUmljYXJkbyB3b3JkIGNsb3VkIC0tLS0Kd29yZF9SIDwtIENvcnB1cyhWZWN0b3JTb3VyY2UoUmljYXJkbyRzZW50ZW5jZV9sb3dlcmVkKSkKd29yZF9SIDwtIHRtX21hcCh3b3JkX1IsIHN0cmlwV2hpdGVzcGFjZSkKd29yZF9SIDwtIHRtX21hcCh3b3JkX1IsIGNvbnRlbnRfdHJhbnNmb3JtZXIodG9sb3dlcikpCndvcmRfUiA8LSB0bV9tYXAod29yZF9SLCByZW1vdmVXb3Jkcywgc3RvcHdvcmRzKCJlbmdsaXNoIikpCndvcmRfUiA8LSB0bV9tYXAod29yZF9SLCByZW1vdmVXb3JkcywgY2hhcmFjdGVyKDApKQp3b3JkX1IgPC0gdG1fbWFwKHdvcmRfUiwgcmVtb3ZlUHVuY3R1YXRpb24pCndvcmRfUiA8LSB0bV9tYXAod29yZF9SLCByZW1vdmVOdW1iZXJzKQpkd29yZF9SIDwtIFRlcm1Eb2N1bWVudE1hdHJpeCh3b3JkX1IpCm13b3JkX1IgPC0gYXMubWF0cml4KGR3b3JkX1IpCnNvcnQgPC0gc29ydChyb3dTdW1zKG13b3JkX1IpLGRlY3JlYXNpbmcgPSBUUlVFKQpkdF9SIDwtIGRhdGEuZnJhbWUod29yZCA9IG5hbWVzKHNvcnQpLGZyZXEgPSBzb3J0KQojIyMjIFNtaXRoIHdvcmQgY2xvdWQgLS0tLQp3b3JkX1MgPC0gQ29ycHVzKFZlY3RvclNvdXJjZShTbWl0aCRzZW50ZW5jZV9sb3dlcmVkKSkKd29yZF9TIDwtIHRtX21hcCh3b3JkX1MsIHN0cmlwV2hpdGVzcGFjZSkKd29yZF9TIDwtIHRtX21hcCh3b3JkX1MsIGNvbnRlbnRfdHJhbnNmb3JtZXIodG9sb3dlcikpCndvcmRfUyA8LSB0bV9tYXAod29yZF9TLCByZW1vdmVXb3Jkcywgc3RvcHdvcmRzKCJlbmdsaXNoIikpCndvcmRfUyA8LSB0bV9tYXAod29yZF9TLCByZW1vdmVXb3JkcywgY2hhcmFjdGVyKDApKQp3b3JkX1MgPC0gdG1fbWFwKHdvcmRfUywgcmVtb3ZlUHVuY3R1YXRpb24pCndvcmRfUyA8LSB0bV9tYXAod29yZF9TLCByZW1vdmVOdW1iZXJzKQpkd29yZF9TIDwtIFRlcm1Eb2N1bWVudE1hdHJpeCh3b3JkX1MpCm13b3JkX1MgPC0gYXMubWF0cml4KGR3b3JkX1MpCnNvcnQgPC0gc29ydChyb3dTdW1zKG13b3JkX1MpLGRlY3JlYXNpbmcgPSBUUlVFKQpkdF9TIDwtIGRhdGEuZnJhbWUod29yZCA9IG5hbWVzKHNvcnQpLGZyZXEgPSBzb3J0KQpgYGAKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLndpZHRoID0gNCwgZmlnLmhlaWdodCA9IDh9CiMjIyBjb21wYXJpc29uIG9mIHRvcCAxMCBmcmVxdWVudCB3b3JkcyAtLS0tCnBsb3RfSyA8LSBnZ3Bsb3QoZHRfS1sxOjEwLF0sIGFlcyh4ID0gcmVvcmRlcih3b3JkLC1mcmVxKSx5ID0gZnJlcSkpICsgZ2VvbV9jb2woZmlsbCA9ICdjb3JhbDEnKSArIGdlb21fdGV4dChhZXMobGFiZWwgPSBmcmVxKSwgdmp1c3QgPSAtMC41KSArIGxhYnMoeCA9ICJXb3JkIiwgeSA9ICJDb3VudCIpICsgZ2d0aXRsZSgiS2V5bmVzIikgCnBsb3RfUiA8LSBnZ3Bsb3QoZHRfUlsxOjEwLF0sIGFlcyh4ID0gcmVvcmRlcih3b3JkLC1mcmVxKSx5ID0gZnJlcSkpICsgZ2VvbV9jb2woZmlsbCA9ICdjaGFydHJldXNlMScpICsgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGZyZXEpLCB2anVzdCA9IC0wLjUpICsgbGFicyh4ID0gIldvcmQiKSArIGdndGl0bGUoIlJpY2FyZG8iKSArIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSkKcGxvdF9TIDwtIGdncGxvdChkdF9TWzE6MTAsXSwgYWVzKHggPSByZW9yZGVyKHdvcmQsLWZyZXEpLHkgPSBmcmVxKSkgKyBnZW9tX2NvbChmaWxsID0gJ2Rhcmt0dXJxdW9pc2UnKSArIGdlb21fdGV4dChhZXMobGFiZWwgPSBmcmVxKSwgdmp1c3QgPSAtMC41KSArIGxhYnMoeCA9ICJXb3JkIikgKyBnZ3RpdGxlKCJTbWl0aCIpICsgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpKQpncmlkLmFycmFuZ2UocGxvdF9LLCBwbG90X1IsIHBsb3RfUywgbmNvbCA9IDEsIHRvcCA9ICJjb21wYXJpc29uIG9mIHRvcCAxMCBmcmVxdWVudCB3b3JkcyBieSBhdXRob3IiKSAKYGBgCgpOb3RpY2VkIHRoZSAiY29ybiIgd29yZCBzaG93biBpbiB0aGUgUmljYXJkbyBmcmVxdWVudCB3b3JkLCBpdCBzdXBwb3J0cyB0aGUgZmFjdCB0aGF0IGhlIGNvbmNlcm5lZCB0aGUgQ29ybiBMYXdzIGltcG9zZWQgYnkgdGhlIEJyaXRpc2ggZ292ZXJubWVudC4gCiAKIyMjIFNlbnRpbWVudCBhbmFseXNpcyAKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CiMjIyMgS2V5bmVzIC0tLS0KZW1vX0sgPC0gZ2V0X25yY19zZW50aW1lbnQoS2V5bmVzJHNlbnRlbmNlX2xvd2VyZWQpCnJlc3VsdF9LIDwtIGRhdGEuZnJhbWUodChlbW9fSykpCiNyb3dTdW1zIGNvbXB1dGVzIGNvbHVtbiBzdW1zIGFjcm9zcyByb3dzIGZvciBlYWNoIGxldmVsIG9mIGEgZ3JvdXBpbmcgdmFyaWFibGUuCm5ld19yZXN1bHRfSyA8LSBkYXRhLmZyYW1lKHJvd1N1bXMocmVzdWx0X0spKQojbmFtZSByb3dzIGFuZCBjb2x1bW5zIG9mIHRoZSBkYXRhZnJhbWUKbmFtZXMobmV3X3Jlc3VsdF9LKVsxXSA8LSAiY291bnQiCm5ld19yZXN1bHRfSyA8LSBjYmluZCgic2VudGltZW50IiA9IHJvd25hbWVzKG5ld19yZXN1bHRfSyksIG5ld19yZXN1bHRfSykKcm93bmFtZXMobmV3X3Jlc3VsdF9LKSA8LSBOVUxMCiMgcGxvdCAKc2xpY2VzX0sgPC0gbmV3X3Jlc3VsdF9LWzE6OCwiY291bnQiXQpsYmxzX0sgPC0gcGFzdGUobmV3X3Jlc3VsdF9LJHNlbnRpbWVudCwgcm91bmQoc2xpY2VzX0svc3VtKHNsaWNlc19LKSoxMDApLCAiJSIsIHNlcCA9ICIiKQoKIyMjIyBSaWNhcmRvIC0tLS0KZW1vX1IgPC0gZ2V0X25yY19zZW50aW1lbnQoUmljYXJkbyRzZW50ZW5jZV9sb3dlcmVkKQpyZXN1bHRfUiA8LSBkYXRhLmZyYW1lKHQoZW1vX1IpKQpuZXdfcmVzdWx0X1IgPC0gZGF0YS5mcmFtZShyb3dTdW1zKHJlc3VsdF9SKSkKbmFtZXMobmV3X3Jlc3VsdF9SKVsxXSA8LSAiY291bnQiCm5ld19yZXN1bHRfUiA8LSBjYmluZCgic2VudGltZW50IiA9IHJvd25hbWVzKG5ld19yZXN1bHRfUiksIG5ld19yZXN1bHRfUikKcm93bmFtZXMobmV3X3Jlc3VsdF9SKSA8LSBOVUxMCgpzbGljZXNfUiA8LSBuZXdfcmVzdWx0X1JbMTo4LCJjb3VudCJdCmxibHNfUiA8LSBwYXN0ZShuZXdfcmVzdWx0X1Ikc2VudGltZW50LCByb3VuZChzbGljZXNfUi9zdW0oc2xpY2VzX1IpKjEwMCksICIlIiwgc2VwID0gIiIpCgojIyMjIFNtaXRoIC0tLS0KZW1vX1MgPC0gZ2V0X25yY19zZW50aW1lbnQoU21pdGgkc2VudGVuY2VfbG93ZXJlZCkKcmVzdWx0X1MgPC0gZGF0YS5mcmFtZSh0KGVtb19TKSkKbmV3X3Jlc3VsdF9TIDwtIGRhdGEuZnJhbWUocm93U3VtcyhyZXN1bHRfUykpCm5hbWVzKG5ld19yZXN1bHRfUylbMV0gPC0gImNvdW50IgpuZXdfcmVzdWx0X1MgPC0gY2JpbmQoInNlbnRpbWVudCIgPSByb3duYW1lcyhuZXdfcmVzdWx0X1MpLCBuZXdfcmVzdWx0X1MpCnJvd25hbWVzKG5ld19yZXN1bHRfUykgPC0gTlVMTAoKc2xpY2VzX1MgPC0gbmV3X3Jlc3VsdF9TWzE6OCwiY291bnQiXQpsYmxzX1MgPC0gcGFzdGUobmV3X3Jlc3VsdF9TJHNlbnRpbWVudCwgcm91bmQoc2xpY2VzX1Mvc3VtKHNsaWNlc19TKSoxMDApLCAiJSIsIHNlcCA9ICIiKQpgYGAKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CnBhcihtZnJvdyA9IGMoMSwzKSkKcGllKHggPSBzbGljZXNfSywgbGFiZWwgPSBsYmxzX0ssIGNvbCA9IHJhaW5ib3cobGVuZ3RoKGxibHNfSykpLCBtYWluID0gImVtb3Rpb24gcGllIGNoYXJ0IG9mIEtleW5lcyIpCnBpZSh4ID0gc2xpY2VzX1IsIGxhYmVsID0gbGJsc19SLCBjb2wgPSByYWluYm93KGxlbmd0aChsYmxzX1IpKSwgbWFpbiA9ICJlbW90aW9uIHBpZSBjaGFydCBvZiBSaWNhcmRvIikKcGllKHggPSBzbGljZXNfUywgbGFiZWwgPSBsYmxzX1MsIGNvbCA9IHJhaW5ib3cobGVuZ3RoKGxibHNfUykpLCBtYWluID0gImVtb3Rpb24gcGllIGNoYXJ0IG9mIFNtaXRoIikKYGBgCgojIyBDb25jbHVzaW9uCgpUaGVyZSBpcyBhIGxvdCBvZiBzaW1pbGFyaXR5IGJldHdlZW4gS2V5bmVzLCBSaWNhcmRvICYgU21pdGggc3VjaCBhcyB0aGUgYXZlcmFnZSBzZW50ZW5jZSBsZW5ndGggJiBlbW90aW9uYWwgdG9uZSAodHJ1c3QgPiBhbnRpY2lwYXRpb24gPiBqb3kgPiBzYWRuZXNzIC8gYW5nZXIgLyBmZWFyKSBpbiB0aGVpciB3b3Jrcy4KCkV2ZW4gdGhvdWdoIHRoZSBmcmVxdWVudCB3b3JkcyBhcmUgbm90IHJlYWxseSBpbiBjb21tb24sIHRoZXkgYm90aCB0YWxrZWQgYWJvdXQgbW9uZXksIGNvbW1vZGl0aWVzLCBhbmQgdGhlIGNvdW50cnkgYW5kIGxhYm91ci4gVGhlIGZvcm1lciBpcyB0aGUgY29yZSBvZiB0aGUgbWFya2V0IGVjb25vbXkgKGp1c3QgbGlrZSB0aGUgZWNvbm9taWMgc3lzdGVtIG9mIHRoZSBVbml0ZWQgU3RhdGVzKSBhbmQgdGhlIGxhdHRlciBhcmUgdGhlIGtleXdvcmRzIGluIHRoZSBwb2xpdGljYWwgZmllbGQuIEFzIHNob3duIGluIHRoZSBhbmFseXNpcyBvZiBlbW90aW9uLCBldmVuIHRob3VnaCB0aGV5IHdlcmUgYm9ybiBhdCBkaWZmZXJlbnQgdGltZXMsIHRoZWlyIHBhc3Npb24gZm9yIGNhcGl0YWxpc3QgcGhpbG9zb3BoeSBpcyB0aGUgc2FtZS4KCgoKCgoKCg==